package com.fs.jzzn.controller;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j;

import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.fs.activiti5.service.ActivitiService;
import com.fs.base.pojo.Attachment;
import com.fs.base.pojo.Org;
import com.fs.base.pojo.User;
import com.fs.base.repository.AttachmentRepository;
import com.fs.base.repository.UserRepository;
import com.fs.base.utils.ApplicationUtils;
import com.fs.base.utils.ExcelUtils;
import com.fs.base.vo.DataGrid;
import com.fs.base.vo.JsonResponse;
import com.fs.base.vo.SysPath;
import com.fs.jzzn.pojo.Expense;
import com.fs.jzzn.pojo.ExpenseItem;
import com.fs.jzzn.repository.ExpenseRepository;
import com.fs.jzzn.service.ExpenseService;

/**
 * @author TiddlerCJ
 * @desc 工程支出业务类
 */
@Controller
@RequestMapping("/console/expense/rewrite")
@Log4j
public class ExpenseController {
	@Autowired private ExpenseRepository expenseRepository;
	@Autowired private ExpenseService expenseService;
	@Autowired  private ActivitiService activitiService;
	@Autowired private UserRepository userRepository;
	@Getter @Setter @Value("${layui.upload.path}")
    private String layuiUploadPath;
	
	@Transactional
	@ResponseBody
	@RequestMapping("newAdd")
	public JsonResponse newAdd(Expense exp, HttpServletRequest request) {
		try {
			String childJson = request.getParameter("childJson");
			List<ExpenseItem> childs = JSON.parseArray(childJson,ExpenseItem.class);
			String expenseId = expenseService.saveOrUpdata(exp, childs);
			
			String start = request.getParameter("saveAndStart");
			if(StringUtils.isNotBlank(start) && "true".equals(start)){
				return start(expenseId);
			}
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	
	@ResponseBody
	@RequestMapping("modify")
	public JsonResponse modify(Expense exp, HttpServletRequest request) {
		try {
			Map<String, Object> map = ApplicationUtils.getRequestDatas();
			Expense oldVo = expenseService.getExpenseRepository().findOne(exp.getId());
			
			String oldJson = JSON.toJSONString(oldVo);
			@SuppressWarnings("unchecked")
			Map<String, Object> oldMap = JSON.parseObject(oldJson, Map.class);
			oldMap.putAll(map);
			
			String json = JSON.toJSONString(oldMap) ;
			
			Expense newVo = JSON.parseObject(json, Expense.class);
			
			String childJson = request.getParameter("childJson");
			List<ExpenseItem> childs = JSON.parseArray(childJson,ExpenseItem.class);
			expenseService.saveOrUpdata(newVo, childs);
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	@Transactional
	@GetMapping("delete")
	@ResponseBody
	public JsonResponse delete(String id) {
		try {
			Expense expense = expenseRepository.findOne(id);
			String processInstanceId = expense.getProcessInstanceId();
			if(StringUtils.isNotBlank(processInstanceId)){
				activitiService.deleteProcessInstance(processInstanceId);
			}
			expenseService.delete(id);
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	@Transactional
	@GetMapping("reset")
	@ResponseBody
	public JsonResponse reset(String expenseId) {
		try {
			if(StringUtils.isNotBlank(expenseId)){
				Expense expense = expenseRepository.findOne(expenseId);
				String processInstanceId = expense.getProcessInstanceId();
				if(StringUtils.isNotBlank(processInstanceId)){
					activitiService.deleteProcessInstance(processInstanceId);
				}
				expense.setStatus("待启动");
				expense.setProcessInstanceId(null);
				expenseRepository.save(expense);
			}
			return JsonResponse.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	
	
	/**
	 * 支出审核
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/check")
	public JsonResponse check(String status,String msg,String id){
		expenseRepository.check(status,msg, id);
		return JsonResponse.success("设置成功!");
	}
	
	/**
	 * 跳转到审核界面
	 * @return
	 */
	@RequestMapping("/preCheck")
	public String preCheck(){
		return "/console/expense/view";
	}
	
	
	/**
	 * 管理人员查看所有工程支出
	 * @return
	 */
	@RequestMapping("/indexAll")
	public String indexAll(HttpServletRequest request){
		request.setAttribute("className", "com.fs.jzzn.pojo.Expense");
		request.setAttribute("modleName", "expense");
		return "/console/expense/indexAll";
	}
	
	
	/**
	 * 支出流程启动
	 */
	@ResponseBody
	@RequestMapping("/start")
	public JsonResponse start(String id){
		Expense expense = expenseRepository.findOne(id);
		//User user = userRepository.findOne(expense.getCreaterId());
		String orgNo = expense.getOrgNo();
		if(StringUtils.isBlank(orgNo)){
			return JsonResponse.success("当前记录组织机构为空，请先设定组织!");
		}
		Org org = activitiService.getOrgRepository().findByOrgNo(orgNo);
		if(StringUtils.isBlank(org.getOrgLeader())){
			return JsonResponse.success("当前记录的组织机构没有配置负责人，请联系管理员配置后再提交!");
		}
		//User leader = userRepository.findOne(org.getOrgLeader());
		boolean flag = activitiService.startExpenseProcess(expense);
		if(flag){
			return JsonResponse.success("启动成功!");
		}else{
			return JsonResponse.error("启动失败!");
		}
	}
	
	@RequestMapping("/preStart")
	public String preStart(String id){
		return "/console/expense/start";
	}
	
	
	/**
	 * 显示流程表单
	 * @param taskId
	 * @param request
	 * @return
	 */
	@GetMapping("viewTaskForm")
	public String viewTaskForm(String taskId,HttpServletRequest request){
		String url = activitiService.findTaskFormKeyByTaskId(taskId);
		if(url.indexOf("?")>-1){
			url = url.concat("&taskId=").concat(taskId);
		}else{
			url = url.concat("?taskId=").concat(taskId);
		}
		return "redirect:".concat(url);
	}
	
	/**
	 * 流程执行表单重定向
	 * @param req
	 * @return
	 */
	@GetMapping("expenseProcessForm")
	public String expenseProcessForm(String taskId,HttpServletRequest request) {
		Task task = activitiService.findTaskById(taskId);
		String businessKey = activitiService.getBusinessKeyByTaskId(taskId);
		Expense expense = null;
		if(StringUtils.isNotBlank(businessKey)){
			expense = expenseRepository.findOne(businessKey.split("\\.")[1]);
		}
		if(expense!=null){
			request.setAttribute("expenseNo",expense.getExpenseNo());
		}
		request.setAttribute("taskId",taskId);
		
		//路由线路名称集合
		Set<String> outComeList = activitiService.findTaskLinesByTaskId(taskId);
		request.setAttribute("outComeList",JSON.toJSON(outComeList));
		
		//String candidataUsers = activitiService.findTaskCandidataUsersByTaskId(taskId);
		//System.out.println(candidataUsers);
		/*
		 * 当前节点任务名称
		 */
		request.setAttribute("taskName",task.getName());
		
		return SysPath.BACK_PATH.concat("/expense/processForm");
	}
	
	@Transactional
	@RequestMapping("submitTask")
	public String submitTask(String taskId, String outcome,String comment, Expense expense) {
		Task task = activitiService.findTaskById(taskId);
		//String outcome =  request.getParameter("outcome"); 
		if("默认提交".equals(outcome)){ outcome = "提交"; }
		
		//String comment = request.getParameter("comment");
		String processInstanceId = task.getProcessInstanceId();
		String createId = expense.getCreaterId();
		User creatorUser = userRepository.findOne(createId);
		String orgNo = creatorUser.getOrgNo();
		
		if(StringUtils.isNotBlank(expense.getOrgNo())){
			orgNo= expense.getOrgNo();
		}
		
		//1-总部审批线路    0-其他项目部审批
		Integer orgType = 0;
		if(StringUtils.isNotBlank(orgNo) && orgNo.startsWith("000001")){
			orgType = 1;
		}
		
		/*if(StringUtils.isNotBlank(expense.getExpenseNo())){
			Expense _expense = expenseRepository.findByExpenseNo(expense.getExpenseNo());
			String _orgNo = _expense.getOrgNo();
			System.out.println("_orgNo:"+ _orgNo);
			if(StringUtils.isNotBlank(_expense.getOrgNo()) && _expense.getOrgNo().startsWith("000001")){
				orgType = 1;
			}
		}*/
		
		//洪湖高速线路项目部，报销流程和总部一致
		/*if(StringUtils.isNotBlank(orgNo) && orgNo.startsWith("00000309")){
			orgType = 2;
		}*/
		
		
		//1-浙江    0-湖北
		Integer isZj = 0;
		if(StringUtils.isNotBlank(orgNo) && orgNo.startsWith("000002")){
			isZj = 1;
		}
		
		/*
		 * 添加批注
		 */
		if(StringUtils.isBlank(comment)){  
			comment = outcome;
		}
		Authentication.setAuthenticatedUserId(ApplicationUtils.User().getNickName());
		comment =  "["+ task.getName() +"]"+ comment;
		activitiService.getTaskService().addComment(taskId, processInstanceId, comment);
		
		
		Map<String, Object> variables = new HashMap<String, Object>();
		/*
		 * 指定下个环节审批人
		 */
		Authentication.setAuthenticatedUserId(ApplicationUtils.User().getNickName());
		
		/*
		 * 参数添加
		 */
		variables.put("orgType",orgType);
		variables.put("isZj",isZj);
		
		if(StringUtils.isNotBlank(outcome)){
			variables.put("outcome", outcome);
		}
		activitiService.getTaskService().complete(taskId, variables);
		
		/*
		 * 流程完结
		 */
		String pid = task.getProcessInstanceId();
		 ProcessInstance rpi = activitiService.getRuntimeService()//
                .createProcessInstanceQuery()//创建流程实例查询对象
                .processInstanceId(pid)
                .singleResult();
		 if(rpi==null ){
			 expense = expenseRepository.findOne(expense.getId());
			 expense.setStatus("完结");
			 expenseRepository.save(expense);
		 }
		
		return "redirect:".concat(SysPath.BACK_PATH.concat("/activiti/task/todo?success=true"));
	}
	
	/**
	 * 查看流程执行状态
	 * @param req
	 * @param id
	 * @return
	 */
	@RequestMapping("flow")
	public String flow(HttpServletRequest req,String id){
		Expense expense = expenseRepository.findOne(id);
		if(expense==null){
			req.setAttribute("message", "当前项目记录已经删除！");
		}else{
			/*String flowId = expense.getFlowId();
			if(StringUtils.isNotBlank(flowId)){
				List<Flow> nodes = flowService.getFlowRepository().findByParentIdOrderByFlowOrderAsc(flowId);
				Flow currentNode = flowService.getCurrentNode(flowId, id);
				if(currentNode==null){
					currentNode = flowService.getFirstNode(flowId);
				}
				req.setAttribute("nodes", nodes);
				req.setAttribute("currentNodeId", currentNode==null? "": currentNode.getId());
			}*/
		}
		return SysPath.BACK_PATH.concat("/expense/flow");
	}
	
	
	@ResponseBody
	@RequestMapping("getImportDataGrid")
	public JsonResponse upload(String id){
		DataGrid grid = new DataGrid();
		try {
			AttachmentRepository aRepository = (AttachmentRepository) ApplicationUtils.getBean("attachmentRepository");
			Attachment attachment = aRepository.findOne(id);
			if(attachment!=null){
				List<List<String>> data = ExcelUtils.readData(attachment.getUrl());
				if(data.size()>0){ data.remove(0); } //去标题栏
				
				List<ExpenseItem> eList = ExpenseItem.excelDataFormat(data);
				if(!CollectionUtils.isEmpty(eList)){
					grid = 	DataGrid.gridBuilder(eList);
				}
				/*
				 * 读取完成，删除临时文件
				 */
				try {
					String path = attachment.getUrl();				
					File file = new File(path);
					if(file.exists()){
						file.delete();
					}
					aRepository.delete(attachment);
				} catch (Exception e) {
					e.printStackTrace();
				} 
			}
			return JsonResponse.success(grid);
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			return JsonResponse.error(e.getMessage());
		}
	}
	
	
}
